%     FASTENER DOCTOR - программа для лечения и конвертации крепежа
%     Copyright (C) 2018  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

clear all; %#ok<CLALL>
clc;
more off;

% #######################################################################################################
% ##                                                                                                   ##
% ##                                        НАСТРОЙКИ ПРОГРАММЫ                                        ##
% ##                                                                                                   ##
% #######################################################################################################

% Для включения возможности вывода информации на русском языке при выполнении программы в среде GNU Octave
% необходимо добавить в файл C:\Octave\Octave-4.4.0\share\octave\site\m\startup\octaverc  следующую строку:
% system("chcp 1251",1);

% ---------------------------------------- Параметры базы Patran ----------------------------------------

Next_Node_Number               = 11867; % Следующий номер узла в базе Patran.                           Где смотреть:   Elements -> Create -> Node -> значение поля Node ID List
Next_Element_Number            = 5924; % Следующий номер элемента в базе Patran.                       Где смотреть:   Elements -> Create -> Element -> значение поля Element ID List
Next_MPC_Number                = 96; % Следующий номер MPC в базе Patran.                            Где смотреть:   Elements -> Create -> MPC -> значение поля MPC ID
Next_Curve_Number              = 3; % Следующий номер кривой в базе Patran.                         Где смотреть:   Geometry -> Create -> Curve -> значение поля Curve ID List
Next_Coord_Number              = 3; % Следующий номер системы координат в базе Patran.              Где смотреть:   Geometry -> Create -> Coord -> значение поля Coord ID List
Next_FD_PSet_Number            = 1; % Следующий номер property set с префиксом FD в базе Patran.    Где смотреть:   Properties -> Create -> список property set'ов. Пример: если FD_000000325 последний в базе, то нужно задать Next_FD_PSet_Number = 326. Если таких property set'ов в базе нет, то нужно задать Next_FD_PSet_Number = 1. 

% --------------------------------------- Параметры ввода-вывода ----------------------------------------

Work_Directory                 = 'M:\Patran_work'; % Рабочая папка
Input_BDF_name                 = 'test_2'; % Имя bdf файла

% -------------------------------------- Конфигурирование заданий ---------------------------------------

% Порядок выполнения заданий

Task_Order = '43'; % Задания выполняются в порядке следования их номеров в строке Task_Order. Если цифра отсутствует, то задание соответствующего типа не будет выполняться. Пример: Task_Order = '241'.

% [ТИП ЗАДАНИЯ 1] - Починка болтов Рутмана

RutFast_Repair_Bush            = 'TRUE'; % TRUE | FALSE             % Починка ориентации и жесткостей BUSH-элементов (также будет произведена починка систем координат в узлах болта)
RutFast_Repair_Offsets         = 'TRUE'; % TRUE | FALSE | REMOVE    % Починка или удаление офсетов точек смятия
RutFast_Repair_2D_Holes        = 'FALSE'; % TRUE | FALSE             % Перемещение центрального узла MPC или bar-паука в центр 2D отверстия (ВНИМАНИЕ! Есть ограничения! См. руководство пользователя)
RutFast_Repair_3D_Holes        = 'FALSE'; % TRUE | FALSE             % Перемещение центрального узла MPC или bar-паука в центр 3D отверстия (ВНИМАНИЕ! Есть ограничения! См. руководство пользователя)
RutFast_Repair_Coord           = 'TRUE'; % TRUE | FALSE             % Починка систем координат в узлах болта
RutFast_Repair_RBAR_DOFs       = 'TRUE'; % TRUE | FALSE             % Починка/модификация степеней свободы RBAR (также будет произведена починка систем координат в узлах болта). См. настройку RutFast_Axial_Constraint в разделе дополнительных параметров заданий.

% [ТИП ЗАДАНИЯ 2] - Починка балочных болтов

BarFast_Repair_Offsets         = 'TRUE'; % TRUE | FALSE | REMOVE    % Починка или удаление офсетов точек смятия
BarFast_Repair_2D_Holes        = 'FALSE'; % TRUE | FALSE             % Перемещение центрального узла MPC или bar-паука в центр 2D отверстия (ВНИМАНИЕ! Есть ограничения! См. руководство пользователя)
BarFast_Repair_3D_Holes        = 'FALSE'; % TRUE | FALSE             % Перемещение центрального узла MPC или bar-паука в центр 3D отверстия (ВНИМАНИЕ! Есть ограничения! См. руководство пользователя)

% [ТИП ЗАДАНИЯ 3] - Конвертация крепежа

Fastener_Convertion            = 'ALL_BAR_TO_RUTMAN'; % ALL_BAR_TO_RUTMAN | ALL_RUTMAN_TO_BAR     % Конвертация крепежа (также будет произведена починка офсетов точек смятия). См. настройку RutFast_Axial_Constraint в разделе дополнительных параметров заданий.

% [ТИП ЗАДАНИЯ 4] - Построение осей распознанного крепежа в Patran с помощью линий

Bolt_Shank_Length_Multiplier   = 2; % Множитель, на который будет умножена длина стержня болта

% [ТИП ЗАДАНИЯ 5] - Преобразование сеток в местах установки крепежа

Convert_Mesh_From              = 'PLATE'; % Код исходного типа сеток (cм. таблицу кодов сеток)
Convert_Mesh_To                = 'PLATE_RBE2_PARALLEL'; % Код сетки, в который необходимо конвертировать исходный тип (см. таблицу кодов сеток)

Quad_RBE2_Stiffen_Strategy     = 'DIAGONAL'; % EDGE | DIAGONAL | ALL_DIR    % Стратегия раскидывания лучей RBE2 на прямоугольные оболочечные элементы: EDGE - вдоль ребер, DIAGONAL - вдоль диагоналей, ALL_DIR - вдоль ребер и диагоналей. Данная настройка используется, когда выполняются соответствующие преобразования сетки в пределах группы 1.
Bar_Spider_PSet_Name           = 'bars_d10'; % Название имеющегося в модели property set, к которому будут привязаны созданные балочные элементы. Данная настройка используется, когда "пауки" из RBE2 преобразуются в "пауки" из балок. (ВНИМАНИЕ! Для конвертации RBE2 в "паук" из балок необходимо, чтобы в bdf файле существовал хотя бы один балочный элемент, имеющий данный property set!).

                                                                     % Перечень возможных кодов сеток и их краткое описание (подробное описание доступно в руководстве пользователя).
                                                                     % Можно выполнять взаимное преобразование сеток в пределах одной группы.
                                                                     %
                                                                     % Группа |        Код сетки         |                              Краткое описание
                                                                     % ------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                     %    1   | PLATE                    | Оболочечные элементы
                                                                     %    1   | PLATE_RBE2_PARALLEL      | Оболочечные элементы с локальным усилением из RBE2 (независимый узел RBE2 принадлежит оболочечным элементам)
                                                                     %    1   | PLATE_RBE2_SEQUENTIAL    | Оболочечные элементы с локальным усилением из RBE2 (независимый узел RBE2 не принадлежит оболочечным элементам)
                                                                     % ------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                     %    2   | RBE2_2D_HOLE             | Явное отверстие в сетке из оболочечных элементов с "пауком" из RBE2
                                                                     %    2   | BAR_SPIDER_2D_HOLE       | Явное отверстие в сетке из оболочечных элементов с "пауком" из балочных элементов
                                                                     % ------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                     %    3   | RBE2_3D_HOLE             | Явное отверстие в сетке из твердотельных элементов с "пауком" из RBE2
                                                                     %    3   | BAR_SPIDER_3D_HOLE       | Явное отверстие в сетке из твердотельных элементов с "пауком" из балочных элементов
                                                                     % ------------------------------------------------------------------------------------------------------------------------------------------------------

% Дополнительные параметры заданий

RutFast_Axial_Constraint       = 'RBAR_DOF'; % RBAR_DOF | USER_BC    % Метод закрепления болта Рутмана от поворота вокруг своей оси:
                                                                     %     RBAR_DOF - посредством передачи вращательной степени свободы первым RBAR-элементом;
                                                                     %     USER_BC - через граничное условие, задаваемое пользователем самостоятельно. (ВНИМАНИЕ! В этом случае программа освободит стержень болта по осевому вращению. Пользователь должен сам задать граничное условие R3 = 0 в одном из узлов стержня болта!)
                                                                     % Данная настройка используется:
                                                                     %     - при починке болтов Рутмана, когда параметр RutFast_Repair_RBAR_DOFs установлен в значение TRUE;
                                                                     %     - при конвертации болтов, когда параметр Fastener_Convertion установлен в значение ALL_BAR_TO_RUTMAN.

% -------------------------------------------------------------------------------------------------------

% #######################################################################################################
% ##                                                                                                   ##
% ##                                     КОНЕЦ НАСТРОЕК ПРОГРАММЫ                                      ##
% ##                                                                                                   ##
% #######################################################################################################

% -----------------------------------------------

global software_version; %                      1
global software_date; %                         1
global software_year; %                         1

global ErrCode; %                               1
global Progress_Bar_Segments; %                 1
global Progress_Bar_Delay; %                    1
global Progress_Bar_Elm_Threshold; %            1

global MAT2_orthotropic_tolerance_multiplier; % 1
global MAT9_orthotropic_tolerance_multiplier; % 1
global MAT2_C_zero_det_tolerance; %             1
global MAT9_C_zero_det_tolerance; %             1
global Laminate_offset_round_tolerance; %       1
global Orientation_Vector_zero_tolerance; %     1
global Global_equivalence_tolerance; %          1
global Field_Zero_Record_Tolerance; %           1
global Field_Nonzero_Record_Tolerance; %        1

global DB_NODES; %                              1
global DB_ELEMENTS; %                           1
global DB_MPC; %                                1
global DB_MATERIALS; %                          1
global DB_PSETS; %                              1
global DB_COORD; %                              1
global DB_FIELDS; %                             1

global AT_NODES; %                              1
global AT_ELEMENTS; %                           1
global AT_MPC; %                                1
global AT_MATERIALS; %                          1
global AT_PSETS; %                              1
global AT_COORD; %                              1
global AT_FIELDS; %                             1

global AT_Page_Prealloc_Size; %                 1
global db_Next_Field_Number; %                  1
global BDF_Entity_Read_Settings; %              1

% -----------------------------------------------

global K_Relative_Tolerance; %                  2
global I12_Tolerance; %                         2
global I1_I2_Relative_Tolerance; %              2
global J_I1_I2_Relative_Tolerance; %            2
global RA_RI_Relative_Tolerance; %              2
global Bolt_shank_deg_tolerance; %              2
global Plate_normal_deg_tolerance; %            2
global Plate_mat_ori_deg_tolerance; %           2
global Bolt_plate_deg_tolerance; %              2
global Offset_relative_tolerance; %             2
global Equidistant_hole_tolerance; %            2

global AST_NODES; %                             2
global AST_COORD; %                             2
global AST_PSETS; %                             2
global AST_MATERIALS; %                         2

global DB_FASTENERS; %                          2
global Diagnostic_Data; %                       2

% -----------------------------------------------

global OUTPUT_DATA %                            3

global Cylindrical_CID_R_Tolerance; %           3
global CID_Vector_zero_tolerance; %             3
global Ref_Dir_Vector_zero_tolerance; %         3
global Coord_Origin_Bolt_Dist_tolerance %       3
global Coord_Z_Bolt_Axis_deg_tolerance; %       3
global Coord_Z_Mapping_deg_tolerance; %         3
global Bush_K_Zero_Tolerance; %                 3
global Bush_K_Relative_Tolerance; %             3
global Bush_Coord_Dir_deg_tolerance; %          3
global Plate_RBE2_Seq_Center_tolerance; %       3

global db_Next_Curve_Number; %                  3
global db_Next_Node_Number; %                   3
global db_Next_MPC_Number; %                    3
global db_Next_Element_Number; %                3
global db_Next_Coord_Number; %                  3
global db_Next_PSet_Number; %                   3
global db_Next_FD_PSet_Number; %                3

global asm_line_2point_created_ids; %           3
global fem_create_nodes__nodes_created; %       3
global fem_delete_node_deleted_ids; %           3
global fem_delete_node_not_found_ids; %         3
global fem_modify_node__nodes_modified; %       3
global fem_delete_mpc_nmpc; %                   3
global fem_delete_mpc_idmpcs; %                 3
global fem_delete_mpc_nnon; %                   3
global fem_delete_mpc_idnoexist; %              3
global fem_delete_mpc_deleted_ids; %            3
global fem_create_elemen_elems_created; %       3
global fem_modify_elem__elems_modified; %       3
global fem_delete_element_nelem; %              3
global fem_delete_element_idelems; %            3
global fem_delete_element_nnon; %               3
global fem_delete_element_idnoexist; %          3
global fem_delete_element_deleted_ids; %        3
global asm_create_cord_3po_created_ids; %       3
global asm_delete_coord_deleted_ids; %          3

% -----------------------------------------------

software_version = []; %                        1
software_date = []; %                           1
software_year = []; %                           1

ErrCode = 0; %                                  1
Progress_Bar_Segments = []; %                   1
Progress_Bar_Delay = []; %                      1
Progress_Bar_Elm_Threshold = []; %              1

MAT2_orthotropic_tolerance_multiplier = []; %   1
MAT9_orthotropic_tolerance_multiplier = []; %   1
MAT2_C_zero_det_tolerance = []; %               1
MAT9_C_zero_det_tolerance = []; %               1
Laminate_offset_round_tolerance = []; %         1
Orientation_Vector_zero_tolerance = []; %       1
Global_equivalence_tolerance = []; %            1
Field_Zero_Record_Tolerance = []; %             1
Field_Nonzero_Record_Tolerance = []; %          1

DB_FIELDS = []; %                               1
AT_FIELDS = []; %                               1

AT_Page_Prealloc_Size = []; %                   1
db_Next_Field_Number = 1; %                     1
BDF_Entity_Read_Settings = []; %                1

% -----------------------------------------------

K_Relative_Tolerance = []; %                    2
I12_Tolerance = []; %                           2
I1_I2_Relative_Tolerance = []; %                2
J_I1_I2_Relative_Tolerance = []; %              2
RA_RI_Relative_Tolerance = []; %                2
Bolt_shank_deg_tolerance = []; %                2
Plate_normal_deg_tolerance = []; %              2
Plate_mat_ori_deg_tolerance = []; %             2
Bolt_plate_deg_tolerance = []; %                2
Offset_relative_tolerance = []; %               2
Equidistant_hole_tolerance = []; %              2

Diagnostic_Data = []; %                         2

% -----------------------------------------------

Cylindrical_CID_R_Tolerance = []; %             3
CID_Vector_zero_tolerance = []; %               3
Ref_Dir_Vector_zero_tolerance = []; %           3
Coord_Origin_Bolt_Dist_tolerance = []; %        3
Coord_Z_Bolt_Axis_deg_tolerance = []; %         3
Coord_Z_Mapping_deg_tolerance = []; %           3
Bush_K_Zero_Tolerance = []; %                   3
Bush_K_Relative_Tolerance = []; %               3
Bush_Coord_Dir_deg_tolerance = []; %            3
Plate_RBE2_Seq_Center_tolerance = []; %         3

db_Next_Curve_Number = Next_Curve_Number; %     3
db_Next_Node_Number = Next_Node_Number; %       3
db_Next_MPC_Number = Next_MPC_Number; %         3
db_Next_Element_Number = Next_Element_Number; % 3
db_Next_Coord_Number = Next_Coord_Number; %     3
db_Next_PSet_Number = []; %                     3
db_Next_FD_PSet_Number = Next_FD_PSet_Number; % 3

asm_line_2point_created_ids = 0; %              3
fem_create_nodes__nodes_created = 0; %          3
fem_delete_node_deleted_ids = 0; %              3
fem_delete_node_not_found_ids = 0; %            3
fem_modify_node__nodes_modified = 0; %          3
fem_delete_mpc_nmpc = 0; %                      3
fem_delete_mpc_idmpcs = 0; %                    3
fem_delete_mpc_nnon = 0; %                      3
fem_delete_mpc_idnoexist = 0; %                 3
fem_delete_mpc_deleted_ids = 0; %               3
fem_create_elemen_elems_created = 0; %          3
fem_modify_elem__elems_modified = 0; %          3
fem_delete_element_nelem = 0; %                 3
fem_delete_element_idelems = 0; %               3
fem_delete_element_nnon = 0; %                  3
fem_delete_element_idnoexist = 0; %             3
fem_delete_element_deleted_ids = 0; %           3
asm_create_cord_3po_created_ids = 0; %          3
asm_delete_coord_deleted_ids = 0; %             3

% -----------------------------------------------

% Отсчет времени выполнения программы
tic;

% Инициализация базовых переменных
Init_Variables ();

% Инициализация допусков
Init_Tolerances ();

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Печать приветствия
Print_Greeting ();

% Корректировка Work_Directory

if (Work_Directory(length(Work_Directory)) == '\')
    Work_Directory = Work_Directory(1:length(Work_Directory)-1);
end

% Корректировка имени bdf файла

if ((length(Input_BDF_name) > 4) && strcmp(Input_BDF_name(length(Input_BDF_name)-3:length(Input_BDF_name)), '.bdf'))
    Input_BDF_name = Input_BDF_name(1:length(Input_BDF_name)-4);
end

% Полный путь к bdf файлу

BDF_File_Path = [Work_Directory '\' Input_BDF_name '.bdf'];

% Проверка строки Task_Order

if (isempty(Task_Order))
    
    fprintf (1, 'Пустая строка параметра Task_Order !\n');
    ErrCode = -1;
    
end

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

for i=1:length(Task_Order)
    
    if (isempty(strfind('12345', Task_Order(i)))) %#ok<STREMP> % Для совместимости с GNU Octave вместо if (~contains('12345', Task_Order(i)))
        fprintf (1, 'Недопустимое значение символа №%i в строке параметра Task_Order !\n', i);
        ErrCode = -1;
    end
    
end

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Проверка параметров заданий

switch RutFast_Repair_Offsets
    case {'TRUE', 'FALSE', 'REMOVE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Offsets !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE, REMOVE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Repair_2D_Holes
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_2D_Holes !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Repair_3D_Holes
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_3D_Holes !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Repair_Bush
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Bush !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Repair_Coord
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_Coord !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Repair_RBAR_DOFs
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Repair_RBAR_DOFs !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch RutFast_Axial_Constraint
    case {'RBAR_DOF', 'USER_BC'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра RutFast_Axial_Constraint !\n');
        fprintf (1, 'Разрешенные значения: RBAR_DOF, USER_BC\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch BarFast_Repair_Offsets
    case {'TRUE', 'FALSE', 'REMOVE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_Offsets !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE, REMOVE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch BarFast_Repair_2D_Holes
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_2D_Holes !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch BarFast_Repair_3D_Holes
    case {'TRUE', 'FALSE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра BarFast_Repair_3D_Holes !\n');
        fprintf (1, 'Разрешенные значения: TRUE, FALSE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Fastener_Convertion
    case {'ALL_RUTMAN_TO_BAR', 'ALL_BAR_TO_RUTMAN'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Fastener_Convertion !\n');
        fprintf (1, 'Разрешенные значения: ALL_RUTMAN_TO_BAR, ALL_BAR_TO_RUTMAN\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

if (Bolt_Shank_Length_Multiplier <= 0)
    ErrCode = -1;
    fprintf (1, 'Недопустимое значение параметра Bolt_Shank_Length_Multiplier !\n');
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

switch Convert_Mesh_From
    case {'PLATE', 'PLATE_RBE2_PARALLEL', 'PLATE_RBE2_SEQUENTIAL', 'RBE2_2D_HOLE', 'BAR_SPIDER_2D_HOLE', 'RBE2_3D_HOLE', 'BAR_SPIDER_3D_HOLE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Convert_Mesh_From !\n');
        fprintf (1, 'Разрешенные значения: PLATE, PLATE_RBE2_PARALLEL, PLATE_RBE2_SEQUENTIAL, RBE2_2D_HOLE, BAR_SPIDER_2D_HOLE, RBE2_3D_HOLE, BAR_SPIDER_3D_HOLE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Convert_Mesh_To
    case {'PLATE', 'PLATE_RBE2_PARALLEL', 'PLATE_RBE2_SEQUENTIAL', 'RBE2_2D_HOLE', 'BAR_SPIDER_2D_HOLE', 'RBE2_3D_HOLE', 'BAR_SPIDER_3D_HOLE'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Convert_Mesh_To !\n');
        fprintf (1, 'Разрешенные значения: PLATE, PLATE_RBE2_PARALLEL, PLATE_RBE2_SEQUENTIAL, RBE2_2D_HOLE, BAR_SPIDER_2D_HOLE, RBE2_3D_HOLE, BAR_SPIDER_3D_HOLE\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

switch Quad_RBE2_Stiffen_Strategy
    case {'EDGE', 'DIAGONAL', 'ALL_DIR'}
        % Допустимые значения
    otherwise
        ErrCode = -1;
        fprintf (1, 'Недопустимое значение параметра Quad_RBE2_Stiffen_Strategy !\n');
        fprintf (1, 'Разрешенные значения: EDGE, DIAGONAL, ALL_DIR\n');
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
end

JT_Convertion_Check_Result = Check_JT_Convertion(Convert_Mesh_From, Convert_Mesh_To);

if (JT_Convertion_Check_Result == -1)
    ErrCode = -1;
    fprintf (1, 'Невозможно выполнить конвертацию сетки типа %s в тот же тип!\n', Convert_Mesh_From);
    fprintf (1, 'Измените значения параметра Convert_Mesh_From, либо Convert_Mesh_To.\n');
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

if (JT_Convertion_Check_Result == 0)
    ErrCode = -1;
    fprintf (1, 'Невозможно выполнить конвертацию сетки типа %s в несовместимый с ней тип %s !\n', Convert_Mesh_From, Convert_Mesh_To);
    fprintf (1, 'Конвертация сеток возможна только в пределах одной группы совместимости (см. руководство пользователя).\n');
    fprintf (1, 'Измените значения параметра Convert_Mesh_From, либо Convert_Mesh_To.\n');
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% ======== Этап создания модели ========

fprintf (1, 'СОЗДАНИЕ МОДЕЛИ\n\n');

% Чтение bdf файла

[DB_NODES, ELEMENTS, MPC, MATERIALS, PSETS, COORD] = Read_BDF(BDF_File_Path);

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Создание адресных таблиц

[AT_COORD, AT_NODES, AT_MPC, AT_MATERIALS, AT_ELEMENTS, AT_PSETS] = Create_Address_Tables(COORD, MPC, MATERIALS, ELEMENTS, PSETS);
 
 if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end
 
% --- Проверка объектов ---

% Проверка узлов

if (~isempty(DB_NODES))

    Check_Nodes();

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

end

% Проверка MPC

if (~isempty(MPC))

    Check_MPC(MPC);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

end

% Проверка материалов

if (~isempty(MATERIALS))

    Check_Materials(MATERIALS);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

end

% Проверка property sets

if (~isempty(PSETS))

    Check_Psets(PSETS, MATERIALS, COORD);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

end

% Проверка элементов

if (~isempty(ELEMENTS))

    Check_Elements(ELEMENTS, PSETS, COORD);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end

end

% --- Обработка объектов и создание баз данных ---

% Обработка систем координат

if (~isempty(COORD))
    
    DB_COORD = Create_DB_COORD(COORD);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear COORD;

end

% Обработка узлов

if (~isempty(DB_NODES))

    Fill_DB_NODES_Locations();

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear NODES;

end

% Обработка MPC

if (~isempty(MPC))

    DB_MPC = Create_DB_MPC(MPC);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear MPC;

end

% Обработка материалов

if (~isempty(MATERIALS))

    DB_MATERIALS = Create_DB_MATERIALS(MATERIALS);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear MATERIALS;

end

% Обработка property sets

if (~isempty(PSETS))

    DB_PSETS = Create_DB_PSETS(PSETS);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear PSETS;

end

% Обработка элементов

if (~isempty(ELEMENTS))

    DB_ELEMENTS = Create_DB_ELEMENTS(ELEMENTS);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
    clear ELEMENTS;

end

% --- Вывод статистики ---

fprintf (1, '\nСтатистика модели:\n\n');

if (strcmp(BDF_Entity_Read_Settings.Read_NODES, 'ON'))
    fprintf (1, '               Узлов: %i\n', size(DB_NODES,1));
end

if (strcmp(BDF_Entity_Read_Settings.Read_PSETS_ELEMENTS, 'ON'))
    fprintf (1, '           Элементов: %i\n', size(DB_ELEMENTS,1));
end

if (strcmp(BDF_Entity_Read_Settings.Read_MPC, 'ON'))
    fprintf (1, '                 MPC: %i\n', size(DB_MPC,1));
end

if (strcmp(BDF_Entity_Read_Settings.Read_MATERIALS, 'ON'))
    fprintf (1, '          Материалов: %i\n', size(DB_MATERIALS,1));
end

if (strcmp(BDF_Entity_Read_Settings.Read_PSETS_ELEMENTS, 'ON'))
    fprintf (1, '       Property sets: %i\n', size(DB_PSETS,1));
end

if (strcmp(BDF_Entity_Read_Settings.Read_COORD, 'ON'))
    fprintf (1, '    Систем координат: %i\n', size(DB_COORD,1));
end

Print_Delimiter();


% ------------------------------------------------ ФОРМАТ ГЛОБАЛЬНЫХ БАЗ ДАННЫХ ------------------------------------------------

% DB_NODES | .ID | .Ref_Location(3,1) | .Location(3,1) | .Reference_CID | .Analysis_CID |

% DB_ELEMENTS (Tet | Wedge | Hex) | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |
% DB_ELEMENTS (Quad | Tria)       | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |
% DB_ELEMENTS (Bar)               | .type | .ID | .Prop_ID | .N_nodes | .Nodes(N_nodes,1) |

% DB_MPC (RBAR) | .type | .ID | .ind_grid | .ind_DOF (в СК анализа узла ind) | .dep_grid | .dep_DOF (в СК анализа узла dep) |
% DB_MPC (RBE2) | .type | .ID | .ind_grid | .dep_grid(:,1) | .dep_DOF (в СК анализа узлов dep) |
% DB_MPC (RBE3) | .type | .ID | .ind_data(:,3) | .dep_grid | .dep_DOF (в СК анализа узла dep) |
%            .ind_data(i,:) | weight_i | ind_grid_i | dof_i (в СК анализа узла ind_grid_i) |

% DB_MATERIALS (isotropic)      | .type | .ID | .Patran_name | .E | .nu |
% DB_MATERIALS (2d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .nu12 | .G12 |
% DB_MATERIALS (2d_anisotropic) | .type | .ID | .Patran_name | .C(3,3) - матрица Гука |                                         ### Сдвиговые деформации инженерные
% DB_MATERIALS (3d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .E3 | .G12 | .G23 | .G13 | .nu12 | .nu23 | .nu13 |   ### nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (3d_anisotropic) | .type | .ID | .Patran_name | .C(6,6) - матрица Гука |                                         ### Сдвиговые деформации инженерные # Расшифровка номеров сдвиговых компонент: 4 - 12, 5 - 23, 6 - 13 # nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (pshell_MAT2_for_transverse_shear) | .type | .ID | .Patran_name | .C(2,2) - матрица Гука |

% DB_PSETS ( PSOLID) | .type | .ID | .Patran_name | .Mat_ID | .Ori_CID (-1, если element coordinate system) |
% DB_PSETS ( PCOMP)  | .type | .ID | .Patran_name | .Patran_laminate_name | .N_plies | .Laminate(:,3) | .Laminate_offset |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
%             .Laminate(i,3) | Mat_ID_i | t_i | Theta_i |
% DB_PSETS ( PCOMPG) | .type | .ID | .Patran_name | .Patran_laminate_name | .N_plies | .Laminate(:,4) | .Laminate_offset |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
%             .Laminate(i,4) | Mat_ID_i | t_i | Theta_i | Global_ply_ID_i |
% DB_PSETS ( PSHELL) | .type | .ID | .Patran_name | .Mat_ID_membrane | .Mat_ID_bending | .Mat_ID_transverse_shear | .t |
%                    | .Ori_Field_ID | .Offset_Field_ID |         DB_FIELDS{Ori_Field_ID}.Value_data(:,2) [Value_data(j,1) - ori_type: (0 - CID | 1 - Angle)] [Value_data(j,2) - ori_data]
% DB_PSETS (  PBUSH) | .type | .ID | .Patran_name | .K(6,1) | .Ori_CID_Field_ID |
% DB_PSETS (   PROD) | .type | .ID | .Patran_name | .Mat_ID | .Area | .J |
% DB_PSETS (PBMSECT) | .type | .ID | .Patran_name | .Mat_ID | .Cross_section_form | .Section_data |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (PBRSECT) | .type | .ID | .Patran_name | .Mat_ID | .Cross_section_form | .Section_data |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (   PBAR) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
% DB_PSETS (  PBARL) | .type | .ID | .Patran_name | .Mat_ID | .Shape | .Dim(:,1) |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Shape = (ROD, TUBE, TUBE2, L, I, CHAN, T, BOX, BAR, CROSS, H, T1, I1, CHAN1, Z, CHAN2, T2, BOX1, HEXA, HAT, HAT1, DBOX )
% DB_PSETS (  PBEAM) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 | .S1 | .S2 | .N1_A | .N2_A | .N1_B | .N2_B |
%                    | .N_intermediate_states | .Intermediate_states_data{N_intermediate_states,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Intermediate_states_data{i} : { .Location | .A | .I1 | .I2 | .I12 | .J }
% DB_PSETS ( PBEAML) | .type | .ID | .Patran_name | .Mat_ID | .Shape | .Dim(:,1) | .N_intermediate_states | .Intermediate_states_data{N_intermediate_states,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Intermediate_states_data{i} : { .Location | .Dim(:,1) }
%             .Shape = (ROD, TUBE, TUBE2, L, I, CHAN, T, BOX, BAR, CROSS, H, T1, I1, CHAN1, Z, CHAN2, T2, BOX1, HEXA, HAT, HAT1, DBOX )
% DB_PSETS ( PBCOMP) | .type | .ID | .Patran_name | .Mat_ID | .Area | .I1 | .I2 | .I12 | .J | .K1 | .K2 | .N1 | .N2 | .SYMOPT | .N_lumped_areas | .Lumped_area_data{N_lumped_areas,1} |
%                    | .Ori_vector_Field_ID | .Offset_vector_A_Field_ID | .Offset_vector_B_Field_ID | .Pinned_DOFs_A_Field_ID | .Pinned_DOFs_B_Field_ID |     (вектора ориентации и офсетов в глобальной СК)
%             .Lumped_area_data{i} : { .Y | .Z | .C | .MID }

% DB_COORD | .ID | .type (Rectangular | Cylindrical) | .e_x (.e_r) | .e_y(.e_t) | .e_z | .origin |

% DB_FIELDS | .ID | .Dim | .Default | .AT{:,1} | .ID_data{:,1} | .Value_data{:,1} |

% ------------------------------------------------------------------------------------------------------------------------------

% -------------------------------------------------- ПЕРЕЧЕНЬ АДРЕСНЫХ ТАБЛИЦ --------------------------------------------------

% AT_NODES(:,1)
% AT_ELEMENTS(:,1)
% AT_MPC(:,1)
% AT_MATERIALS(:,1)
% AT_PSETS(:,1)
% AT_COORD(:,1)
% AT_FIELDS(:,1)

% ------------------------------------------------------------------------------------------------------------------------------

% ----------------------------------------- ФУНКЦИИ ДЛЯ ДОСТУПА К СВОЙСТВАМ ЭЛЕМЕНТОВ ------------------------------------------

%               [Ori_type, Ori_data] = Get_Shell_Orientation(Element_ID)
%                             Offset = Get_Shell_Offset(Element_ID)    (см. описание функции)
%                             Offset = Get_Plate_Offset(Element_ID)    (см. описание функции)
%                            Ori_CID = Get_Bush_Ori_CID(Element_ID)
%                         Ori_vector = Get_Bar_Ori_Vector(Element_ID)
% [Offset_vector_A, Offset_vector_B] = Get_Bar_Offset_Vectors(Element_ID)
%     [Pinned_DOFs_A, Pinned_DOFs_B] = Get_Bar_Pinned_DOFs(Element_ID)

% ------------------------------------------------------------------------------------------------------------------------------


% ##############################################################################################################################
% ##                                                                                                                          ##
% ##   С ЭТОГО МОМЕНТА НА ОСНОВЕ ДАННОГО КОДА МОЖНО СОЗДАВАТЬ ДРУГИЕ ПРОГРАММЫ, ИСПОЛЬЗУЮЩИЕ ДАННЫЕ ИЗ СФОРМИРОВАННОЙ БАЗЫ    ##
% ##                                                                                                                          ##
% ##############################################################################################################################


% ======== Этап распознавания крепежа ========

fprintf (1, 'РАСПОЗНАВАНИЕ КРЕПЕЖА\n\n');

% Создание таблиц ассоциативности

[AST_NODES, AST_COORD, AST_PSETS, AST_MATERIALS] = Create_Associativity_Tables();

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Распознавание крепежа

DB_FASTENERS = Recognize_Fasteners();

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

Print_Delimiter();

% ------------------------------- ФОРМАТ ТАБЛИЦ АССОЦИАТИВНОСТИ --------------------------------

% AST_NODES{:,1}
%             ->.Elm_list(:,1)
%             ->.MPC_list(:,1)
%
% AST_COORD{:,1}
%             ->.Node_list(:,1)
%             ->.PSet_list(:,1)
%
% AST_PSETS{:,1}
%             ->.Elm_list(:,1)
%
% AST_MATERIALS{:,1}
%             ->.PSet_list(:,1)

% ----------------------------------------------------------------------------------------------

% --------------------------------- ФОРМАТ БАЗЫ ДАННЫХ КРЕПЕЖА ---------------------------------

% DB_FASTENERS{:,1}
%                ->.topology   ('bar_fastener' | 'rutman_fastener')
%  bar  rut
% | +  | + |     ->.N_layers
% | +  | + |     ->.Shank_nodes(:,1)
% | +  | + |     ->.Shank_elements(:,1)
% | [] | + |     ->.Additional_nodes(:,1)
% | [] | + |     ->.RBAR_MPCs(:,1)
% | [] | + |     ->.Head_MPC_Index         % Индекс элемента массива RBAR_MPCs
% | [] | + |     ->.Bush_elements{:,1}
% | +  | + |     ->.Offset_MPCs{:,1}
% | +  | + |     ->.Joint_nodes(:,1)
% | +  | + |     ->.Joint_topology{:,1}   ('plate' | 'plate_rbe2_sequential' | 'plate_rbe2_parallel' | 'rbe2_2d_hole' | 'rbe2_3d_hole' | 'bar_spider_2d_hole' | 'bar_spider_3d_hole')
% | +  | + |     ->.Joint_mesh{:,1}
%                                ->.MPC_ID
%                                ->.Bar_Spider_Elm_list(:,1)
%                                ->.Bar_Spider_Conn_Nodes_list(:,1)
%                                ->.Element_list(:,1)

% ----------------------------------------------------------------------------------------------

% ------------------------------ ФУНКЦИИ ДЛЯ РАБОТЫ С БАЗОЙ ДАННЫХ ------------------------------

%        Node_ID = DB_Node_Create(Reference_Coord, Analysis_Coord, Location)
%                  DB_Node_Move(Node_ID, New_Location)
%                  DB_Node_Edit_Coord(Node_list, New_Reference_Coord, New_Analysis_Coord)
%                  DB_Node_Delete(Node_list)
% Existence_flag = DB_Node_Exist(Node_ID)
%
%         MPC_ID = DB_MPC_Create_RBE2(Ind_Node, Dep_Node_list, Dep_DOFs)
%         MPC_ID = DB_MPC_Create_RBAR(Ind_Node, Dep_Node, Dep_DOFs)
%                  DB_MPC_Modify_RBE2(MPC_ID, Ind_Node, Dep_Node_list, Dep_DOFs)
%                  DB_MPC_Modify_RBAR(MPC_ID, Ind_Node, Dep_Node, Dep_DOFs)
%                  DB_MPC_Delete(MPC_list)
% Existence_flag = DB_MPC_Exist(MPC_ID)
%
%     Element_ID = DB_Elm_Create_Bar(Node_1, Node_2)
%   Element_list = DB_Elm_Create_Bar_Spider(Node_1, Node_2_list, Pset_ID)
%                  DB_Elm_Modify_Pset(Element_list, Pset_ID)
%                  DB_Elm_Modify_Conn(Element_list, Node_list, Target_Node_list)
%                  DB_Elm_Delete(Element_list)
% Existence_flag = DB_Elm_Exist(Element_ID)
%
%        PSet_ID = DB_PSet_Create_Bush(Pset_Name, Ori_Coord_ID, K1, K2, K3, K4, K5, K6, Elm_list)
%                  DB_PSet_Modify_Bush(PSet_ID, Pset_Name, Ori_Coord_ID, K1, K2, K3, K4, K5, K6, Elm_list)
%                  DB_PSet_Delete(PSet_ID)
% Existence_flag = DB_PSet_Exist(PSet_ID)
% [Flag, Number] = DB_PSet_Is_FD(PSet_ID)
%
%       Coord_ID = DB_Coord_Create_Rect_3P(Location_1, Location_2, Location_3)
%                  DB_Coord_Delete(Coord_list)
% Existence_flag = DB_Coord_Exist(Coord_ID)
%      Free_flag = DB_Coord_Is_Free(Coord_ID)
%
%       Field_ID = DB_Field_Create(Dim)                                                                            1
%                  DB_Field_Add_Record(Field_ID, Item_ID, Item_Value)                                              1
%     Item_Value = DB_Field_Get_Value(Field_ID, Item_ID)                                                           1
% Existence_flag = DB_Field_Exist(Field_ID)                                                                        1
%     Empty_flag = DB_Field_Isempty(Field_ID)                                                                      1
%                  DB_Field_Modify_Record(Field_ID, Item_ID, Item_Value)                                           3
%                  DB_Field_Remove_Record(Field_ID, Item_ID)                                                       3
%  Default_Value = DB_Field_Get_Default_Value(Field_ID)                                                            3
%                  DB_Field_Delete(Field_list)                                                                     3
%  Constant_flag = DB_Field_Isconstant(Field_ID)                                                                   3

% -----------------------------------------------------------------------------------------------

% ----------------------------------------- ФУНКЦИИ PCL -----------------------------------------

% Text = PCL_Node_Create(Reference_Coord, Analysis_Coord, Location)
% Text = PCL_Node_Move(Node_ID, New_Location)
% Text = PCL_Node_Edit_Coord(Node_list, New_Reference_Coord, New_Analysis_Coord)
% Text = PCL_Node_Delete(Node_list)
%
% Text = PCL_MPC_Create_RBE2(Ind_Node, Dep_Node_list, Dep_DOFs)
% Text = PCL_MPC_Create_RBAR(Ind_Node, Dep_Node, Dep_DOFs)
% Text = PCL_MPC_Modify_RBE2(MPC_ID, Ind_Node, Dep_Node_list, Dep_DOFs)
% Text = PCL_MPC_Modify_RBAR(MPC_ID, Ind_Node, Dep_Node, Dep_DOFs)
% Text = PCL_MPC_Delete(MPC_list)
%
% Text = PCL_Elm_Create_Bar(Node_1, Node_2)
% Text = PCL_Elm_Create_Bar_Spider(Node_1, Node_2_list, Pset_Name)
% Text = PCL_Elm_Modify_Pset(Elm_list, Pset_Name)
% Text = PCL_Elm_Modify_Conn(Elm_list, Node_list, Target_Node_list)
% Text = PCL_Elm_Delete(Elm_list)
%
% Text = PCL_PSet_Create_Bush(Pset_Name, Ori_Coord_ID, K1, K2, K3, K4, K5, K6, Elm_list)
% Text = PCL_PSet_Modify_Bush(Pset_Name, New_pset_name, Ori_Coord_ID, K1, K2, K3, K4, K5, K6, Elm_list)
% Text = PCL_PSet_Delete(Pset_Name)
%
% Text = PCL_Coord_Create_Rect_3P(Location_1, Location_2, Location_3)
% Text = PCL_Coord_Delete(Coord_list)
%
% Text = PCL_Curve_Create_2P(Location_1, Location_2)

% -----------------------------------------------------------------------------------------------


% ======== Этап выполнения заданий ========

fprintf (1, 'ВЫПОЛНЕНИЕ ЗАДАНИЙ\n');

fprintf (1, '\nПодготовка:\n\n');

% Инициализация журнала команд
Init_Output_Data();

% Установка следующего номера property set
Set_Next_PSet_Number();

% Проверка счетчиков
Check_Counters();

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

% Цикл по числу заданий
for i=1:length(Task_Order)
    
    switch (Task_Order(i))
        
        case '1'
            
            fprintf (1, '\nЗадание %i из %i - Починка болтов Рутмана\n\n', i, length(Task_Order));
            fprintf (1, '    Параметры задания:\n');
            fprintf (1, '        RutFast_Repair_Bush\t\t = %s\n', RutFast_Repair_Bush);
            fprintf (1, '        RutFast_Repair_Offsets\t = %s\n', RutFast_Repair_Offsets);
            fprintf (1, '        RutFast_Repair_2D_Holes\t = %s\n', RutFast_Repair_2D_Holes);
            fprintf (1, '        RutFast_Repair_3D_Holes\t = %s\n', RutFast_Repair_3D_Holes);
            fprintf (1, '        RutFast_Repair_Coord\t = %s\n', RutFast_Repair_Coord);
            fprintf (1, '        RutFast_Repair_RBAR_DOFs = %s\n', RutFast_Repair_RBAR_DOFs);
            if (strcmp(RutFast_Repair_RBAR_DOFs, 'TRUE'))
                fprintf (1, '        RutFast_Axial_Constraint = %s\n\n', RutFast_Axial_Constraint);
            else
                fprintf (1, '\n');
            end
            
            if (strcmp(RutFast_Repair_Offsets, 'FALSE') && strcmp(RutFast_Repair_2D_Holes, 'FALSE') && ...
                strcmp(RutFast_Repair_3D_Holes, 'FALSE') && strcmp(RutFast_Repair_Bush, 'FALSE') && ...
                strcmp(RutFast_Repair_Coord, 'FALSE') && strcmp(RutFast_Repair_RBAR_DOFs, 'FALSE'))
                
                fprintf (1, '    Задание не выполнено, так как не сконфигурировано для выполнения каких-либо действий.\n');
                
            else
                
                N_RutFast = Count_Rutman_Fasteners();

                if (ErrCode < 0)
                    break;
                end

                if (N_RutFast > 0)

                    Task_Repair_RutFast(RutFast_Repair_Offsets, RutFast_Repair_2D_Holes, RutFast_Repair_3D_Holes, RutFast_Repair_Bush, RutFast_Repair_Coord, RutFast_Repair_RBAR_DOFs, RutFast_Axial_Constraint);

                    if (ErrCode < 0)
                        break;
                    end

                else
                    fprintf (1, '    На текущий момент в модели не содержится болтов Рутмана. Задание отменено.\n');
                end
                
            end
            
        case '2'
            
            fprintf (1, '\nЗадание %i из %i - Починка балочных болтов\n\n', i, length(Task_Order));
            fprintf (1, '    Параметры задания:\n');
            fprintf (1, '        BarFast_Repair_Offsets\t = %s\n', BarFast_Repair_Offsets);
            fprintf (1, '        BarFast_Repair_2D_Holes\t = %s\n', BarFast_Repair_2D_Holes);
            fprintf (1, '        BarFast_Repair_3D_Holes\t = %s\n\n', BarFast_Repair_3D_Holes);
            
            if (strcmp(BarFast_Repair_Offsets, 'FALSE') && strcmp(BarFast_Repair_2D_Holes, 'FALSE') && strcmp(BarFast_Repair_3D_Holes, 'FALSE'))
                
                fprintf (1, '    Задание не выполнено, так как не сконфигурировано для выполнения каких-либо действий.\n');
                
            else
                
                N_BarFast = Count_Bar_Fasteners();

                if (ErrCode < 0)
                    break;
                end

                if (N_BarFast > 0)

                    Task_Repair_BarFast(BarFast_Repair_Offsets, BarFast_Repair_2D_Holes, BarFast_Repair_3D_Holes);

                    if (ErrCode < 0)
                        break;
                    end

                else
                    fprintf (1, '    На текущий момент в модели не содержится балочных болтов. Задание отменено.\n');
                end
                
            end
            
        case '3'
            
            fprintf (1, '\nЗадание %i из %i - Конвертация болтов\n\n', i, length(Task_Order));
            fprintf (1, '    Параметры задания:\n');
            fprintf (1, '        Fastener_Convertion \t = %s\n', Fastener_Convertion);
            if (strcmp(Fastener_Convertion, 'ALL_BAR_TO_RUTMAN'))
                fprintf (1, '        RutFast_Axial_Constraint = %s\n\n', RutFast_Axial_Constraint);
            else
                fprintf (1, '\n');
            end
            
            switch Fastener_Convertion
                    
                case 'ALL_RUTMAN_TO_BAR'
                    
                    N_RutFast = Count_Rutman_Fasteners();
                    
                    if (ErrCode < 0)
                        break;
                    end
                    
                    if (N_RutFast > 0)
                        
                        Task_Convert_Fasteners(Fastener_Convertion, RutFast_Axial_Constraint);

                        if (ErrCode < 0)
                            break;
                        end
                        
                    else
                        fprintf (1, '    На текущий момент в модели не содержится болтов Рутмана. Задание отменено.\n');
                    end
                    
                case 'ALL_BAR_TO_RUTMAN'
                    
                    N_BarFast = Count_Bar_Fasteners();
                    
                    if (ErrCode < 0)
                        break;
                    end
                    
                    if (N_BarFast > 0)
                        
                        Task_Convert_Fasteners(Fastener_Convertion, RutFast_Axial_Constraint);

                        if (ErrCode < 0)
                            break;
                        end
                        
                    else
                        fprintf (1, '    На текущий момент в модели не содержится балочных болтов. Задание отменено.\n');
                    end
            
            end
            
        case '4'
            
            fprintf (1, '\nЗадание %i из %i - Построение осей распознанных болтов\n\n', i, length(Task_Order));
            fprintf (1, '    Параметры задания:\n');
            fprintf (1, '        Bolt_Shank_Length_Multiplier\t = %f\n\n', Bolt_Shank_Length_Multiplier);
            
            Task_Plot_Fasteners(Bolt_Shank_Length_Multiplier);

            if (ErrCode < 0)
                break;
            end
            
        case '5'
            
            fprintf (1, '\nЗадание %i из %i - Преобразование сеток в местах установки болтов\n\n', i, length(Task_Order));
            fprintf (1, '    Параметры задания:\n');
            fprintf (1, '        Convert_Mesh_From\t\t\t = %s\n', Convert_Mesh_From);
            fprintf (1, '        Convert_Mesh_To\t\t\t\t = %s\n', Convert_Mesh_To);
            if (strcmp(Convert_Mesh_To, 'PLATE_RBE2_PARALLEL') || strcmp(Convert_Mesh_To, 'PLATE_RBE2_SEQUENTIAL'))
                fprintf (1, '        Quad_RBE2_Stiffen_Strategy\t = %s\n', Quad_RBE2_Stiffen_Strategy);
            end
            if (strcmp(Convert_Mesh_To, 'BAR_SPIDER_2D_HOLE') || strcmp(Convert_Mesh_To, 'BAR_SPIDER_3D_HOLE'))
                fprintf (1, '        Bar_Spider_PSet_Name\t\t = %s\n', Bar_Spider_PSet_Name);
            end
            fprintf (1, '\n');
            
            switch Convert_Mesh_From
                
                case 'PLATE'
                    JT_count = Count_Joint_Topology('plate');
                case 'PLATE_RBE2_PARALLEL'
                    JT_count = Count_Joint_Topology('plate_rbe2_parallel');
                case 'PLATE_RBE2_SEQUENTIAL'
                    JT_count = Count_Joint_Topology('plate_rbe2_sequential');
                case 'RBE2_2D_HOLE'
                    JT_count = Count_Joint_Topology('rbe2_2d_hole');
                case 'BAR_SPIDER_2D_HOLE'
                    JT_count = Count_Joint_Topology('bar_spider_2d_hole');
                case 'RBE2_3D_HOLE'
                    JT_count = Count_Joint_Topology('rbe2_3d_hole');
                case 'BAR_SPIDER_3D_HOLE'
                    JT_count = Count_Joint_Topology('bar_spider_3d_hole');
                
            end
            
            if (JT_count > 0)

                Task_Convert_Joint_Topology(Convert_Mesh_From, Convert_Mesh_To, Quad_RBE2_Stiffen_Strategy, Bar_Spider_PSet_Name);

                if (ErrCode < 0)
                    break;
                end

            else
                fprintf (1, '    На текущий момент в модели не содержится сеток типа %s в местах установки крепежа. Задание отменено.\n', Convert_Mesh_From);
            end
            
        otherwise
            
            fprintf (1, '\nНедопустимое значение символа №%i в строке параметра Task_Order !\n', i);
            ErrCode = -1;
            break;
            
    end
    
end

if (ErrCode < 0)
    fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
    toc;
    return;
end

Print_Delimiter();


% ======== Этап записи результатов ========

fprintf (1, 'ЗАПИСЬ РЕЗУЛЬТАТОВ\n\n');

if (OUTPUT_DATA.string_counter > 0)

    Write_Session_File(Work_Directory);

    if (ErrCode < 0)
        fprintf (1, 'Работа программы завершена с ошибкой!\n\n');
        toc;
        return;
    end
    
else
    
    fprintf (1, 'В процессе выполнения заданий в модели не было сделано ни одного изменения.\n');
    fprintf (1, 'Сессионный файл не создан.\n');

end

Print_Delimiter();

fprintf (1, 'Работа программы завершена успешно!\n\n');

% Вывод времени выполнения программы
toc;
